package com.tools.common.thread;

import com.tools.common.object.Note;
import org.jetbrains.annotations.NotNull;

import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 自定义的线程创建工厂对象，用于线程池创建线程
 * */
@Note("自定义的线程创建工厂对象，用于线程池创建线程")
public final class OwnThreadFactory implements ThreadFactory {

    @Note("线程的自增数字，默认从 1 开始，该数字是原子性的，绝对的线程安全")
    private final AtomicInteger threadNumber = new AtomicInteger(1);

    @Note("新创建的线程名称，可以统一价格前缀")
    private final String threadNamePrefix;

    @Note("新创建的线程所在的线程组")
    private final ThreadGroup threadGroup;

    @Note("是否为守护线程")
    private final boolean isDaemon;

    @Note("线程的优先级。1 为最小，10 为最大，5 为正常。请输入 1 ~ 10 之间的整数")
    private final int threadPriority;

    /* *******************************************************************************************
     *
     *           构造器
     *
     * *******************************************************************************************
     * */

    public OwnThreadFactory() {
        this.threadGroup = Thread.currentThread().getThreadGroup();
        this.threadNamePrefix = "dawn-thread-";
        this.isDaemon = false;
        this.threadPriority = Thread.NORM_PRIORITY;
    }

    public OwnThreadFactory(String threadNamePrefix) {
        this(threadNamePrefix, false, Thread.NORM_PRIORITY);
    }

    public OwnThreadFactory(boolean isDaemon) {
        this(null, isDaemon, Thread.NORM_PRIORITY);
    }

    public OwnThreadFactory(int threadPriority) {
        this(null, false, threadPriority);
    }

    public OwnThreadFactory(String threadNamePrefix, boolean isDaemon) {
        this(threadNamePrefix, isDaemon, Thread.NORM_PRIORITY);
    }

    public OwnThreadFactory(String threadNamePrefix, int threadPriority) {
        this(threadNamePrefix, false, threadPriority);
    }

    public OwnThreadFactory(String threadNamePrefix, boolean isDaemon, int threadPriority) {
        if(threadPriority < 1 || threadPriority > 10) {
            throw new IllegalArgumentException("线程优先级设置错误，优先级的正确数字应该在 1 ~ 10 之间。推荐使用 Thread.xxx 来使用。");
        }
        this.isDaemon = isDaemon;
        this.threadPriority = threadPriority;
        this.threadGroup = Thread.currentThread().getThreadGroup();
        if(threadNamePrefix == null || threadNamePrefix.isEmpty()) {
            this.threadNamePrefix = "dawn-thread-";
            return;
        }
        this.threadNamePrefix = threadNamePrefix;
    }

    /* *******************************************************************************************
     *
     *           其他方法
     *
     * *******************************************************************************************
     * */

    /**
     * @param r Runnable 线程要执行的任务
     * @return 根据传入的 Runnable 任务，创建新线程
     * */
    @Note("根据传入的 Runnable 任务，创建新线程")
    @Override
    public Thread newThread(@NotNull Runnable r) {
        String threadName = threadNamePrefix + threadNumber.getAndIncrement();
        Thread thread = new Thread(threadGroup, r, threadName, 0);
        thread.setPriority(threadPriority);
        thread.setDaemon(isDaemon);
        return thread;
    }


    @Override
    public String toString() {
        return "DefaultThreadFactory{" +
                "threadNameRule=" + threadNamePrefix + "increment" +
                ", isDaemon=" + isDaemon +
                ", threadPriority=" + threadPriority +
                '}';
    }
}
